import 'package:flutter/material.dart';

/// created by hcl
/// on 2024/3/6
/// BarCodeParseUtils
/// desc 彩票条形码解析公用类
class BarCode {
  bool beginG; // 新旧条码区别，TRUE表示G开头，FALSE表示非G开头
  BarCodeMode barCodeMode; // 彩票包装类型(0-箱 1-本 2-张 3-盒(本段))
  String? fadm; // 方案代码
  String? scpc; // 生产批次
  String? xh; // 箱号
  String? bqh; // 本起号（张条码时即本号，盒条码时为该盒本止号）
  String? bzh; // 本止号（张条码时即本号，盒条码时为该盒本止号）
  String? zlsh; // 张流水号
  String? mxbs; // 每箱本数（箱条码时有用）
  String? mbzs; // 每本张数
  String? djyzm; // 兑奖验证码（G开头的保安码为：彩票特征码）
  String? wlyzm; // 物流验证码（G开头的保安码为：中奖信息）

  BarCode({
    required this.beginG,
    required this.barCodeMode,
    this.fadm,
    this.scpc,
    this.xh,
    this.bqh,
    this.bzh,
    this.zlsh,
    this.mxbs,
    this.mbzs,
    this.djyzm,
    this.wlyzm,
  });
}

enum BarCodeMode {
  ///BAR_MODE_BOX(0, "箱"),
  //   BAR_MODE_PIECE(1, "本或张"),
  //   BAR_MODE_NOUSE(2, "张"),//没用到此类型，并入1中，实际手动选择本或张
  //   BAR_MODE_PADRANGEBAR(3, "盒"),
  //   BAR_MODE_SAFE(4, "保安码"),
  //   BAR_MODE_SAFE_SECOND(5, "二次开奖保安码"),
  //   BAR_MODE_MANAGER(6, "管理员"),
  //   BAR_MODE_STORENO(7, "站点"),
  //   BAR_MODE_ORDER(8, "订单号"),
  //   BAR_MODE_INVALID(9, "不合法");

  BAR_MODE_BOX,
  BAR_MODE_PIECE,
  BAR_MODE_NOUSE,
  BAR_MODE_PADRANGEBAR,
  BAR_MODE_SAFE,
  BAR_MODE_SAFE_SECOND,
  BAR_MODE_MANAGER,
  BAR_MODE_STORENO,
  BAR_MODE_ORDER,
  BAR_MODE_INVALID,
}

extension BarCodeModeName on BarCodeMode {
  String get name => getBarCodeModeName(this);
}

String getBarCodeModeName(BarCodeMode barCodeMode) {
  if (barCodeMode == BarCodeMode.BAR_MODE_BOX) {
    return 'box';
  } else if (barCodeMode == BarCodeMode.BAR_MODE_PIECE) {
    return 'piece';
  } else if (barCodeMode == BarCodeMode.BAR_MODE_NOUSE) {
    return 'nouse';
  } else if (barCodeMode == BarCodeMode.BAR_MODE_PADRANGEBAR) {
    return 'pad';
  } else if (barCodeMode == BarCodeMode.BAR_MODE_SAFE) {
    return 'safe';
  } else if (barCodeMode == BarCodeMode.BAR_MODE_SAFE_SECOND) {
    return 'safe2nd';
  } else if (barCodeMode == BarCodeMode.BAR_MODE_MANAGER) {
    return 'mana';
  } else if (barCodeMode == BarCodeMode.BAR_MODE_STORENO) {
    return 'store';
  } else if (barCodeMode == BarCodeMode.BAR_MODE_ORDER) {
    return 'order';
  } else if (barCodeMode == BarCodeMode.BAR_MODE_INVALID) {
    return 'inv';
  } else {
    return 'inv';
  }
}

class BarCodeParseUtils {
  /**
   *
   * @Title:parseBarCode
   * @Description:解析刮刮乐彩票条码格式
   * @param:@param code
   * @param:@return
   * @return:BarCode
   * @throws
   * @Create: 2017年2月24日 下午4:35:31
   * @Author : jason
   */
  static BarCode parseBarCode(String code) {
    bool beginG = false;
    BarCodeMode barMode = BarCodeMode.BAR_MODE_INVALID;

    String? fadm; // 方案代码
    String? scpc; // 生产批次
    String? xh; // 箱号
    String? bqh; // 本起号（张条码时即本号，盒条码时为该盒本止号）
    String? bzh; // 本止号（张条码时即本号，盒条码时为该盒本止号）
    String? zlsh; // 张流水号
    String? mxbs; // 每箱本数（箱条码时有用）
    String? mbzs; // 每本张数
    String? djyzm; // 兑奖验证码（G开头的保安码为：彩票特征码）
    String? wlyzm;

    if (16 == code.length && RegExp("^\\d{16}\$").hasMatch(code)) {
      ///管理员卡  -- 全数字
      if (code[2] == '8' && code[3] == '8') {
        barMode = BarCodeMode.BAR_MODE_MANAGER;
      } else {
        barMode = BarCodeMode.BAR_MODE_ORDER;
      }
    } else if (27 == code.length &&
        RegExp("^[A-Z]{1}\\d{26}\$").hasMatch(code)) {
      ///旧本条码 , 第一位大写英文字母，其余都为数字
      barMode = BarCodeMode.BAR_MODE_PIECE;

      ///length 27和59才用
      code = old2NewBar(code);
      fadm = code.substring(0, 5);
      scpc = code.substring(5, 10);
      bqh = code.substring(16, 23);
      bzh = code.substring(16, 23);
      zlsh = code.substring(23, 26);
      mbzs = code.substring(26, 29);
    } else if (29 == code.length &&
        RegExp("^[A-Z]{1}\\d{28}\$").hasMatch(code)) {
      ///新本条码   第一位大写英文字母，其余都为数字
      barMode = BarCodeMode.BAR_MODE_PIECE;
      fadm = code.substring(0, 5);
      scpc = code.substring(5, 10);
      bqh = code.substring(16, 23);
      bzh = code.substring(16, 23);
      zlsh = code.substring(23, 26);
      mbzs = code.substring(26, 29);
    } else if (31 == code.length &&
        RegExp("^[^G]{1}\\d{30}\$").hasMatch(code)) {
      ///31 新本条码，非G开头   第一位大写英文字母非G开头，其余都为数字
      beginG = true;
      barMode = BarCodeMode.BAR_MODE_PIECE;
      fadm = code.substring(0, 5);
      scpc = code.substring(5, 10);
      bqh = code.substring(10, 17);
      bzh = code.substring(10, 17);
      zlsh = code.substring(17, 20);
      mbzs = code.substring(20, 23);
      wlyzm = code.substring(23, 31);
    } else if (33 == code.length &&
        RegExp("^[A-Z]{1}\\d{32}\$").hasMatch(code)) {
      ///33 盒条码  第一位大写英文字母，其余都为数字
      barMode = BarCodeMode.BAR_MODE_PADRANGEBAR;
      fadm = code.substring(0, 5);
      scpc = code.substring(5, 10);
      bqh = code.substring(19, 26);
      bzh = code.substring(26, 33);
      mxbs = code.substring(13, 16);
      mbzs = code.substring(16, 19);
    } else if (40 == code.length &&
        RegExp("^[^G]{1}\\d{39}\$").hasMatch(code)) {
      ///40 新保安码，非G开头  第一位大写英文字母非G开头，其余都为数字
      beginG = true;
      barMode = BarCodeMode.BAR_MODE_SAFE;
      fadm = code.substring(0, 5);
      scpc = code.substring(5, 10);
      bqh = code.substring(10, 17);
      bzh = code.substring(10, 17);
      zlsh = code.substring(17, 20);
      djyzm = code.substring(20, 30);
      wlyzm = code.substring(30, 40);
    } else if (41 == code.length &&
        RegExp("^[^G]{1}\\d{40}\$").hasMatch(code)) {
      ///41 二次开奖票保安码
      beginG = true;
      barMode = BarCodeMode.BAR_MODE_SAFE_SECOND;
      fadm = code.substring(0, 5);
      scpc = code.substring(5, 10);
      bqh = code.substring(10, 17);
      bzh = code.substring(10, 17);
      zlsh = code.substring(17, 20);
      djyzm = code.substring(20, 30);
      wlyzm = code.substring(30, 40);
    } else if (41 == code.length &&
        RegExp("^(G)\\d{19}[A-R]{16}[a-zA-Z]{2}\\d{3}\$").hasMatch(code)) {
      ///保安码
      beginG = true;
      barMode = BarCodeMode.BAR_MODE_SAFE;
      fadm = code.substring(0, 5);
      scpc = code.substring(5, 10);
      bqh = code.substring(10, 17);
      bzh = code.substring(10, 17);
      zlsh = code.substring(17, 20);
      djyzm = code.substring(20, 36);
      wlyzm = code.substring(36, 41);
    } else if (59 == code.length &&
        RegExp("^[A-Z]{1}\\d{50}(\\.)\\d{1}[a-zA-Z0-9]{6}\$").hasMatch(code)) {
      ///旧箱条码
      barMode = BarCodeMode.BAR_MODE_BOX;
      code = old2NewBar(code);
      fadm = code.substring(0, 5);
      scpc = code.substring(5, 10);
      xh = code.substring(10, 15);
      mxbs = code.substring(15, 18);
      mbzs = code.substring(18, 21);
    } else if (61 == code.length &&
        RegExp("^[A-Z]{1}\\d{54}(\\.)\\d{1}[a-zA-Z0-9]{6}\$").hasMatch(code)) {
      ///旧箱条码
      barMode = BarCodeMode.BAR_MODE_BOX;
      fadm = code.substring(0, 5);
      scpc = code.substring(5, 10);
      xh = code.substring(10, 15);
      mxbs = code.substring(15, 18);
      mbzs = code.substring(18, 21);
    }else if (63 == code.length &&
        RegExp("^[A-Z]{1}\\d{54}(\\.)\\d{1}[a-zA-Z0-9]{6}\$").hasMatch(code)) {
      ///新箱条码
      barMode = BarCodeMode.BAR_MODE_BOX;
      fadm = code.substring(0, 5);
      scpc = code.substring(5, 10);
      xh = code.substring(10, 15);
      mxbs = code.substring(15, 18);
      mbzs = code.substring(18, 21);
    }
    return BarCode(
        beginG: beginG,
        barCodeMode: barMode,
        fadm: fadm,
        scpc: scpc,
        xh: xh,
        bqh: bqh,
        bzh: bzh,
        zlsh: zlsh,
        mbzs: mbzs,
        mxbs: mxbs,
        djyzm: djyzm,
        wlyzm: wlyzm);
  }

  static String old2NewBar(String code) {
    String strTemp = '';
    if (code.length == 27) {
      //旧张条码
      strTemp +=
          '${code.substring(0, 10)}0${code.substring(10, 14)}0${code.substring(14, 27)}';
    } else if (code.length == 59) {
      //旧箱条码
      strTemp +=
          '${code.substring(0, 25)}00${code.substring(25, 32)}0${code.substring(32, 36)}0${code.substring(36, 59)}';
    }
    return strTemp;
  }
}
